package com.qdc.datacenters.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageInfo;
import com.qdc.datacenters.domain.entity.BaseEntity;
import com.qdc.datacenters.domain.entity.ChatMsgRule;
import com.qdc.datacenters.domain.entity.ChatMsgRuleRange;
import com.qdc.datacenters.domain.query.rule.ChatMsgRuleAddQuery;
import com.qdc.datacenters.domain.query.rule.ChatMsgRuleQuery;
import com.qdc.datacenters.domain.query.rule.ChatMsgRuleRangeQuery;
import com.qdc.datacenters.domain.query.rule.ChatMsgTimeoutListQuery;
import com.qdc.datacenters.domain.query.user.SysUserQuery;
import com.qdc.datacenters.domain.vo.rule.*;
import com.qdc.datacenters.domain.vo.user.SysUserVo;
import com.qdc.datacenters.enums.DeleteStatusEnum;
import com.qdc.datacenters.exception.CommonException;
import com.qdc.datacenters.mapper.ChatMsgRuleMapper;
import com.qdc.datacenters.service.IChatMsgRuleMsgService;
import com.qdc.datacenters.service.IChatMsgRuleRangeService;
import com.qdc.datacenters.service.IChatMsgRuleService;
import com.qdc.datacenters.service.ISysUserService;
import com.qdc.datacenters.utils.SecurityUtils;
import com.qdc.datacenters.utils.StrUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 会话超时规则表(ChatMsgRule)表服务实现类
 *
 * @author danmo
 * @since 2024-03-18 10:12:11
 */
@Service
public class ChatMsgRuleServiceImpl extends BaseServiceImpl<ChatMsgRuleMapper, ChatMsgRule> implements IChatMsgRuleService {

    @Autowired
    private IChatMsgRuleRangeService iChatMsgRuleRangeService;

    @Autowired
    private ISysUserService iSysUserService;

    @Autowired
    private IChatMsgRuleMsgService iChatMsgRuleMsgService;

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void add(ChatMsgRuleAddQuery query) {
        checkScope(query.getRangeList());
        ChatMsgRule chatMsgRule = new ChatMsgRule();
        chatMsgRule.setName(query.getName());
        chatMsgRule.setChatType(query.getChatType());
        chatMsgRule.setTimeOut(query.getTimeOut());
        if (save(chatMsgRule)) {
            //保存范围数据
            iChatMsgRuleRangeService.saveBatchByRuleId(chatMsgRule.getId(), query.getRangeList());
        }
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void edit(ChatMsgRuleAddQuery query) {
        checkScope(query.getRangeList());
        ChatMsgRule chatMsgRule = getById(query.getId());
        if (ObjectUtil.isNull(chatMsgRule)) {
            throw new CommonException("无效ID");
        }
        if (StrUtils.isNotBlank(query.getName())) {
            chatMsgRule.setName(query.getName());
        }
        if (Objects.nonNull(query.getTimeOut())) {
            chatMsgRule.setTimeOut(query.getTimeOut());
        }
        if (ObjectUtil.isNotNull(query.getChatType())) {
            chatMsgRule.setChatType(query.getChatType());
        }
        if (updateById(chatMsgRule)) {
            //保存范围数据
            iChatMsgRuleRangeService.updateBatchByRuleId(chatMsgRule.getId(), query.getRangeList());
        }
    }

    @Override
    public void delete(ChatMsgRuleQuery query) {

        Optional.ofNullable(query.getIds()).orElseGet(ArrayList::new).add(query.getId());
        if (CollectionUtil.isEmpty(query.getIds())) {
            return;
        }
        boolean update = update(new LambdaUpdateWrapper<ChatMsgRule>()
                .set(BaseEntity::getDelFlag, DeleteStatusEnum.DELETE_YES.getIndex())
                .set(BaseEntity::getUpdateTime, new Date())
                .set(BaseEntity::getUpdateBy, SecurityUtils.getUserId())
                .in(ChatMsgRule::getId, query.getIds()));
        if (update) {
            iChatMsgRuleRangeService.delBatchByQiIds(query.getIds());
        }
    }

    @Override
    public ChatMsgRuleVo getRuleDetail(ChatMsgRuleQuery query) {
        ChatMsgRule chatMsgRule = getById(query.getId());
        if (ObjectUtil.isNull(chatMsgRule)) {
            throw new CommonException("无效ID");
        }
        ChatMsgRuleVo ruleVo = new ChatMsgRuleVo();
        ruleVo.setId(chatMsgRule.getId());
        ruleVo.setChatType(chatMsgRule.getChatType());
        ruleVo.setName(chatMsgRule.getName());
        ruleVo.setTimeOut(chatMsgRule.getTimeOut());
        List<ChatMsgRuleRange> ruleRangeList = iChatMsgRuleRangeService.getRuleRangeByRuleIds(Collections.singletonList(query.getId()));

        Map<Long, String> userMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(ruleRangeList)) {
            Set<Long> userIdSet = ruleRangeList.stream().map(ChatMsgRuleRange::getUserId).collect(Collectors.toSet());
            SysUserQuery sysUserQuery = new SysUserQuery();
            sysUserQuery.setUserIds(new ArrayList<>(userIdSet));
            List<SysUserVo> userList = iSysUserService.getList(sysUserQuery);
            if (CollectionUtil.isNotEmpty(userList)) {
                userMap = userList.stream().collect(Collectors.toMap(SysUserVo::getUserId, SysUserVo::getNickName, (key1, key2) -> key2));
            }
        }

        List<ChatMsgRuleRangVo> ruleRangeVoList = new LinkedList<>();
        if (CollectionUtil.isNotEmpty(ruleRangeList)) {
            Map<String, List<ChatMsgRuleRange>> rangeUserMap = ruleRangeList.stream().collect(Collectors.groupingBy(ChatMsgRuleRange::getGroupId));
            Map<Long, String> finalUserMap = userMap;
            rangeUserMap.forEach((rangeId, ruleRanges) -> {
                if (CollectionUtil.isNotEmpty(ruleRanges)) {
                    ChatMsgRuleRangVo ruleRangVo = new ChatMsgRuleRangVo();
                    ruleRangVo.setRuleId(ruleRanges.get(0).getRuleId());
                    ruleRangVo.setBTime(ruleRanges.get(0).getBTime());
                    ruleRangVo.setETime(ruleRanges.get(0).getETime());
                    ruleRangVo.setWorkCycle(ruleRanges.get(0).getWorkCycle());
                    List<ChatMsgRuleUserVo> ruleUserList = new LinkedList<>();
                    for (ChatMsgRuleRange ruleRange : ruleRanges) {
                        ChatMsgRuleUserVo ruleUserVo = new ChatMsgRuleUserVo();
                        ruleUserVo.setUserId(ruleRange.getUserId());
                        if (finalUserMap.containsKey(ruleRange.getUserId())) {
                            ruleUserVo.setUserName(finalUserMap.get(ruleRange.getUserId()));
                        }
                        ruleUserList.add(ruleUserVo);
                    }
                    ruleRangVo.setUserList(ruleUserList);
                    ruleRangeVoList.add(ruleRangVo);
                }
            });
        }
        ruleVo.setRangeList(ruleRangeVoList);
        return ruleVo;
    }

    @Override
    public PageInfo<ChatMsgRuleListVo> getRulePageList(ChatMsgRuleQuery query) {
        List<ChatMsgRuleListVo> ruleList = new LinkedList<>();
        List<Long> ruleIdList = this.baseMapper.getRuleIdsByQuery(query);
        if (CollectionUtil.isNotEmpty(ruleIdList)) {
            ChatMsgRuleQuery ruleListQuery = new ChatMsgRuleQuery();
            ruleListQuery.setIds(ruleIdList);
            ruleList = getRuleList(ruleListQuery);
        }
        if (CollectionUtil.isNotEmpty(ruleList)) {
            Set<Long> userIdSet = ruleList.stream().map(ChatMsgRuleListVo::getUserList).flatMap(Collection::stream).map(ChatMsgRuleUserVo::getUserId).collect(Collectors.toSet());
            Map<Long, String> userMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(userIdSet)) {
                SysUserQuery sysUserQuery = new SysUserQuery();
                sysUserQuery.setUserIds(new ArrayList<>(userIdSet));
                List<SysUserVo> userList = iSysUserService.getList(sysUserQuery);
                if (CollectionUtil.isNotEmpty(userList)) {
                    userMap = userList.stream().collect(Collectors.toMap(SysUserVo::getUserId, SysUserVo::getNickName, (key1, key2) -> key2));
                }

                for (ChatMsgRuleListVo chatMsgRuleListVo : ruleList) {
                    if (CollectionUtil.isNotEmpty(chatMsgRuleListVo.getUserList())) {
                        for (ChatMsgRuleUserVo chatMsgRuleUserVo : chatMsgRuleListVo.getUserList()) {
                            if (userMap.containsKey(chatMsgRuleUserVo.getUserId())) {
                                chatMsgRuleUserVo.setUserName(userMap.get(chatMsgRuleUserVo.getUserId()));
                            }
                        }

                    }
                }
            }
        }
        PageInfo<Long> pageIdInfo = new PageInfo<>(ruleIdList);
        PageInfo<ChatMsgRuleListVo> pageInfo = new PageInfo<>(ruleList);
        pageInfo.setTotal(pageIdInfo.getTotal());
        pageInfo.setPageNum(pageIdInfo.getPageNum());
        pageInfo.setPageSize(pageIdInfo.getPageSize());
        return pageInfo;
    }

    @Override
    public List<ChatMsgRuleListVo> getRuleList(ChatMsgRuleQuery query) {
        return this.baseMapper.getRuleList(query);
    }

    @Override
    public List<ChatMsgRuleListVo> getRuleListByUserId(ChatMsgRuleQuery query) {
        return this.baseMapper.getRuleListByUserId(query);
    }

    @Override
    public List<SingleTimeoutListVo> getSingleTimeOutList(ChatMsgTimeoutListQuery query) {
        return iChatMsgRuleMsgService.getSingleTimeOutList(query);
    }

    @Override
    public List<GroupTimeoutListVo> getGroupTimeOutList(ChatMsgTimeoutListQuery query) {
        return iChatMsgRuleMsgService.getGroupTimeOutList(query);
    }

    /**
     * 校验排期是否重复
     *
     * @param rangeList 范围参数
     */
    private void checkScope(List<ChatMsgRuleRangeQuery> rangeList) {
        if (CollectionUtil.isNotEmpty(rangeList)) {
            for (int i = 0; i < rangeList.size() - 1; i++) {
                for (int j = i + 1; j < rangeList.size(); j++) {
                    int finalJ = j;
                    long userSum = rangeList.get(i).getUserIds().stream()
                            .filter(one -> rangeList.get(finalJ).getUserIds().stream()
                                    .anyMatch(two -> ObjectUtil.equal(two, one))).count();

                    if (userSum > 0) {
                        long workCycleSum = rangeList.get(i).getWorkCycle().stream()
                                .filter(one -> rangeList.get(finalJ).getWorkCycle().stream()
                                        .anyMatch(two -> ObjectUtil.equal(two, one))).count();
                        if (workCycleSum > 0) {
                            String beginTime1 = rangeList.get(i).getBeginTime();
                            String endTime1 = rangeList.get(i).getEndTime();
                            String beginTime2 = rangeList.get(finalJ).getBeginTime();
                            String endTime2 = rangeList.get(finalJ).getEndTime();
                            if (match(beginTime1, endTime1, beginTime2, endTime2)) {
                                throw new CommonException("员工时间排期有冲突!");
                            }
                        }
                    }
                }
            }
        }
    }

    private boolean match(String startTime1, String endTime1, String startTime2, String endTime2) {
        DateTime parseStartTime1 = DateUtil.parse(startTime1, "HH:mm");
        DateTime parseEndTime1 = DateUtil.parse(endTime1, "HH:mm");

        DateTime parseStartTime2 = DateUtil.parse(startTime2, "HH:mm");
        DateTime parseEndTime2 = DateUtil.parse(endTime2, "HH:mm");
        return !(parseStartTime2.isAfter(parseEndTime1) || parseStartTime1.isAfter(parseEndTime2));
    }
}

